// 严格模式
"use strict";

/***************************************1.JavaScript 函数语法*********************************/
function funcGrammar() {
    var  ele = document.getElementById('func_grammar');
    ele.innerText = '/***************************************1.JavaScript 函数语法*********************************/\n' +
        '// 1.函数的语法\n' +
        '    function functionname()\n' +
        '    {\n' +
        '        //这里是要执行的代码\n' +
        '    }\n' +
        '\n' +
        '    //有参数\n' +
        '    function myFunction(var1,var2)\n' +
        '    {\n' +
        '        //这里是要执行的代码\n' +
        '    }\n' +
        '\n' +
        '    //参数和返回值的函数\n' +
        '    function myFunction2(var1,var2)\n' +
        '    {\n' +
        '        //这里是要执行的代码\n' +
        '        return var1 + var2;\n' +
        '    }\n' +
        '\n' +
        '    //函数参数特殊字段：\n' +
        '    // 利用arguments，你可以获得调用者传入的所有参数\n' +
        '\n' +
        '\n' +
        '    //ES6之后新的参数rest参数\n' +
        '    // rest参数是一个数组\n' +
        '    // rest参数只能写在最后，前面用...标识\n' +
        '    // 参数不够 rest参数会接收一个空数组\n' +
        '\n' +
        '\n' +
        '\n' +
        '\n' +
        '    //2 .匿名函数  function (x) { ... }是一个匿名函数，它没有函数名\n' +
        '\n' +
        '    var  abc = function (x) {\n' +
        '        return  x * x;\n' +
        '    }\n' +
        '    console.log( abc(3));\n' +
        '\n' +
        '\n' +
        '    //3.自调用函数\n' +
        '    (function () {\n' +
        '        var  x = \'我是自调用函数\';\n' +
        '        console.log(x);\n' +
        '    })();\n' +
        '\n' +
        '\n' +
        '    //4.箭头函数 ES6新增特性\n' +
        '    /*\n' +
        '    (参数1, 参数2, …, 参数N) => { 函数声明 }\n' +
        '\n' +
        '    (参数1, 参数2, …, 参数N) => 表达式(单一)   ==  相当于：(参数1, 参数2, …, 参数N) =>{ return 表达式; }\n' +
        '\n' +
        '    (单一参数) => {函数声明}\n' +
        '\n' +
        '    单一参数 => {函数声明}\n' +
        '\n' +
        '    () => {函数声明}\n' +
        '    */\n' +
        '\n' +
        '    var x = function (x, y) {\n' +
        '        return x + y;\n' +
        '    }\n' +
        '     console.log(\'普通函数\' + x(1,2));\n' +
        '\n' +
        '   var  x2 = (x, y) => {\n' +
        '       return x + y;\n' +
        '   };\n' +
        '   console.log(\'普通箭头函数\' + x2(1,2));\n' +
        '\n' +
        '    var  x3 = (x,y) => x + y;\n' +
        '    console.log(\'最省略的箭头函数\' + x3(1,2));\n' +
        '\n' +
        '    var  x4 = (x,y) => { return x + y;}\n' +
        '    console.log(\'最省略的带中括号的箭头函数\' + x4(1,2))\n' +
        '\n' +
        '\n' +
        '    //5.函数的调用方式 4种  函数默认是窗口的对象函数\n' +
        '\n' +
        '    // 1.普通正常的函数调用  f();\n' +
        '\n' +
        '    // 2.函数作为对象的方法调用 object.method();\n' +
        '\n' +
        '    // 3.作为参数调用函数   a();\n' +
        '\n' +
        '    // 4.使用函数方法调用  object = function.call(object, param1, param2);\n' +
        '    //call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数，两个方法的第一个参数必须是对象本身。\n' +
        '    //apply方法，它接收两个参数，第一个参数就是需要绑定的this变量，第二个参数是Array，表示函数本身的参数 apply 可以改变this的指向\n' +
        '\n' +
        '\n' +
        '   // 6.this   指向调用函数的那个对象';

}

/***************************************2.JavaScript 变量作用域********************************/
function funcvarlet(){
      var  ele = document.getElementById('func_var_let');
      ele.innerText = '/***************************************2.JavaScript 变量作用域********************************/\n' +
          ' // 1.常量、变量表示方法\n' +
          '      // 常量 ES6之前没有 大写表示   const PI = 3.14;\n' +
          '      // 变量 var  let\n' +
          '\n' +
          '      //2.全局变量 - 默认对象是window  全局作用域的变量实际上被绑定到window的一个属性\n' +
          '\n' +
          '      var  course = \'course\';\n' +
          '      function foo() {\n' +
          '          alert(\'foo\');\n' +
          '      }\n' +
          '      window.foo() == foo()\n' +
          '\n' +
          '      //为了很好的处理多个js 使用同样的全局变量，最好的处理方式使用名字空间\n' +
          '      var  FUNC_NAME = {};   //唯一的全局变量FUNC_NAME:\n' +
          '      FUNC_NAME.name = \'app\';\n' +
          '      FUNC_NAME.foo = function () {\n' +
          '          return \'foo\';\n' +
          '      }\n' +
          '\n' +
          '      //3.局部作用域  内部函数可以访问外部函数定义的变量\n' +
          '\n' +
          '\n' +
          '     // 4.变量提升   在函数内部首先申明所有变量原则\n' +
          '\n' +
          '\n' +
          '     // 5.解构赋值  ES6才有  可以同时对一组变量进行赋值\n' +
          '      var  [x, y , z] = [1, 2, 3];\n' +
          '      \n' +
          '     // 6.   this   指向调用函数的那个对象\'; call() 和 apply()  第一个参数可以改变this 指向';











}

/***************************************3.高阶函数*******************************/
function funcgaojie(){
    var  ele = document.getElementById('func_gaojie');
    ele.innerText = '\n/***************************************3.高阶函数*******************************/\n' +
        ' //1.定义：一个函数就接收另一个函数作为参数，这种函数就称之为高阶函数\n' +
        '    function gaojiefunc(x, y, func) {\n' +
        '         return func(x) + func(y);\n' +
        '    }\n' +
        '    var  result = gaojiefunc(-5, 6, Math.abs);\n' +
        '    console.log(result);\n' +
        '\n' +
        '\n' +
        '    //2.高阶函数map\n' +
        '    var  arr = [1,2,3,4,5,6,7,8,9];\n' +
        '    console.log(arr.map(String));\n' +
        '    function pow(x) {\n' +
        '         return x * x;\n' +
        '    }\n' +
        '    console.log(arr.map(pow));\n' +
        '\n' +
        '\n' +
        '    //3.高阶函数 reduce   [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)\n' +
        '    var  arr2 = [1,2,3,4,5,6,7];\n' +
        '\n' +
        '    console.log(arr2.reduce(function (x, y) {\n' +
        '        return x * 10 + y;\n' +
        '    }));\n' +
        '\n' +
        '    //4.高阶函数 filter 用于把Array的某些元素过滤掉，然后返回剩下的元素\n' +
        '     console.log(arr2.filter(function (x) {\n' +
        '         return x%2== 0;\n' +
        '     }));\n' +
        '\n' +
        '     //5.高阶函数 sort  默认把所有元素先转换为String再排序，结果\'10\'排在了\'2\'的前面，因为字符\'1\'比字符\'2\'的ASCII码小。\n' +
        '      var  arr3 = [20, 2, 1, 3, 68, 23, 34];\n' +
        '      console.log(arr3.sort(function (x,y) {\n' +
        '            if(x > y){\n' +
        '                return 1;\n' +
        '            }else  if(x < y){\n' +
        '                return -1;\n' +
        '            }else {\n' +
        '                return 0;\n' +
        '            }\n' +
        '\n' +
        '      }));';



}


/***************************************4.闭包函数*******************************/
function bibaofunc() {
    var  element = document.getElementById('func_bibao');
    element.innerText = '\n/***************************************4.闭包函数*******************************/\n' +
        ' // 1.闭包也是高阶函数 返回函数就是闭包\n' +
        '    // 返回函数不要引用任何循环变量，或者后续会发生变化的变量。\n' +
        '    function lazy_sum(arr) {\n' +
        '        var sum  = function () {\n' +
        '            return arr.reduce(function (x ,y) {\n' +
        '                return x + y;\n' +
        '            });\n' +
        '        }\n' +
        '        return sum;\n' +
        '    }\n' +
        '    console.log(lazy_sum([1,2,3,4,5])());\n' +
        '\n' +
        '\n' +
        '    // 2.创建计时器，给定一个初始值，执行一次加一次并返回\n' +
        '    function create_counter (initalTime) {\n' +
        '          var x = initalTime || 0;\n' +
        '          return {\n' +
        '              addtime :function () {\n' +
        '                  return x + 1;\n' +
        '              }\n' +
        '          };\n' +
        '    }\n' +
        '     var timer = create_counter(10);\n' +
        '     console.log(timer.addtime());\n' +
        '\n' +
        '    var timer2 = create_counter();\n' +
        '    console.log(timer2.addtime());';

   

}

/***************************************5.生成器*******************************/
function genarator() {
    var  ele = document.getElementById('func_genarator');

    ele.innerText = '\n/***************************************5.生成器*******************************/\n' +
        '// 1.定义（ES6才有） 一个generator看上去像一个函数，但可以返回多次。\n' +
        '\n' +
        '    function* foo(x) {\n' +
        '        yield x + 1;\n' +
        '        yield x + 2;\n' +
        '        return x + 3;\n' +
        '    }\n' +
        '    \n' +
        '    // 写一个斐波那契数列\n' +
        '    function  *fib(max) {\n' +
        '         var  a = 1;\n' +
        '         var  b = 2;\n' +
        '         var  n = 0;\n' +
        '         while (n < max){\n' +
        '             yield a;\n' +
        '             [a, b] = [b, a+ b];\n' +
        '             n++;\n' +
        '         }\n' +
        '         return;\n' +
        '    }\n' +
        '\n' +
        '    var foogenator = foo(2);\n' +
        '    console.log(foogenator.next());  // {value : 3, done : flase}\n' +
        '    console.log(foogenator.next());  // {value : 4, done : flase}\n' +
        '    console.log(foogenator.next());  // {value : 5, done : true}\n' +
        '    console.log(foogenator.next());  // {value : undefine, done : true}\n' +
        '    /*\n' +
        '    * next()方法会执行generator的代码，然后，每次遇到yield x;就返回一个对象{value: x, done: true/false}，\n' +
        '    * 然后“暂停”。返回的value就是yield的返回值，done表示这个generator是否已经执行结束了。\n' +
        '    * 如果done为true，则value就是return的返回值。\n' +
        '      当执行到done为true时，这个generator对象就已经全部执行完毕，不要再继续调用next()了。\n' +
        '    *\n' +
        '    * */\n' +
        '\n' +
        '    // 2.直接用for ... of循环迭代generator对象，这种方式不需要我们自己判断done\n' +
        '    for(var x of fib(5)){\n' +
        '        console.log(x);\n' +
        '    }';


}